import Utils from '@/graph/3d/utils'
import { use3DEditorStore } from '@/store'
import { useTresContext } from '@tresjs/core'
import { storeToRefs } from 'pinia'
import * as THREE from 'three'

export default () => {
  const editorStore = use3DEditorStore()
  const context = useTresContext()
  const { handleElement } = storeToRefs(editorStore)
  const keyboardKey = shallowRef('')
  const isTransform = shallowRef(false)
  const matrix = shallowRef(new THREE.Matrix4())
  const origin = shallowRef(new THREE.Vector2())
  const mouse = shallowRef(new THREE.Vector2())
  const mesh = shallowRef<THREE.Object3D>(null)

  const position = shallowRef(new THREE.Vector3())
  const rotation = shallowRef(new THREE.Euler())
  const scale = shallowRef(new THREE.Vector3())

  const direction = shallowRef(new THREE.Vector3())
  const directionName = shallowRef('')

  watch(
    () => handleElement.value,
    () => {
      mesh.value = handleElement.value?.ref
    },
  )

  const onKeyDown = (e: KeyboardEvent) => {
    if (!mesh.value) return
    // g,r,s,x,y,z键值控制
    if ('grsxyz'.includes(e.key)) {
      if (isTransform.value && 'xyz'.includes(e.key)) {
        directionName.value = e.key
        direction.value.setFromMatrixColumn(
          mesh.value.matrixWorld,
          'xyz'.indexOf(e.key),
        )
      }
      else {
        keyboardKey.value = e.key
        isTransform.value = true
        matrix.value.copy(mesh.value.matrixWorld)
        origin.value.copy(mouse.value)

        position.value.copy(mesh.value.position)
        rotation.value.copy(mesh.value.rotation)
        scale.value.copy(mesh.value.scale)
      }
    }
    switch (e.key) {
      case 'g':
        // position.value.copy(mesh.value.position)
        break
      case 'r':
        // rotation.value.copy(mesh.value.rotation)
        break
      case 'Escape':
        isTransform.value = false
        mesh.value.matrixWorld.copy(matrix.value)

        mesh.value.position.copy(position.value)
        mesh.value.rotation.copy(rotation.value)
        mesh.value.scale.copy(scale.value)
        reset()
        break
      default:
        break
    }
  }

  const onPointerDown = (e: PointerEvent) => {
    if (!mesh.value) return
    isTransform.value = false
    reset()
  }
  const onPointerMove = (e: PointerEvent) => {
    mouse.value.set(e.clientX, e.clientY)
    if (!mesh.value || !isTransform.value) return

    switch (keyboardKey.value) {
      case 'g': {
        const offset = new THREE.Vector2()
          .subVectors(mouse.value, origin.value)
          .multiplyScalar(0.05)
        offset.y *= -1

        const offset3D = new THREE.Vector3(
          offset.x,
          offset.y,
          (offset.x + offset.y) * 0.5,
        )

        const translate = directionName.value
          ? offset3D.clone().multiply(direction.value)
          : offset3D

        const pos = new THREE.Vector3().addVectors(position.value, translate)
        mesh.value.position.copy(pos)
        break
      }
      case 'r': {
        // const angle = new THREE.Vector2().copy(mouse.value).angleTo(origin.value)
        const offset = new THREE.Vector2()
          .subVectors(mouse.value, origin.value)
          .multiplyScalar(0.05)
        offset.y *= -1

        // 计算旋转角度
        const angle = Math.atan2(offset.y, offset.x) + Math.PI
        mesh.value.rotateOnWorldAxis(direction.value, angle * 0.05)

        console.log(THREE.MathUtils.radToDeg(angle))

        break
      }
      default:
        break
    }
  }

  const reset = () => {
    direction.value.set(0, 0, 0)
    directionName.value = ''
    keyboardKey.value = ''
  }

  return { keyboardKey, onKeyDown, isTransform, onPointerDown, onPointerMove }
}
